package user.source;

import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
import event.Direction;
import event.Explode;
import event.Missile;
import event.Tank;
import message.MissileDeadMsg;
import message.TankDeadMsg;
import server.TankServer;

/**
 * 
 * @author
 *
 */
public class TankClient extends Frame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4790978758282182797L;
	/**
	 * 定义窗口的宽常量
	 */
	public static final int GAMME_WIDTH = 800;
	/**
	 * 定义窗口的高常量
	 */
	public static final int GAMME_HEIGHT = 600;

	/**
	 * 利用坦克对象创建一个坦克
	 */
	public Tank myTank = new Tank(50, 50, true, Direction.STOP, this);
	Explode e = new Explode(200, 200, this);

	/**
	 * 定义一个列表的炮弹
	 */
	public List<Missile> missiles = new ArrayList<Missile>();
	/**
	 * 定义一个列表的爆炸
	 */
	public List<Explode> explodes = new ArrayList<Explode>();
	/**
	 * 定义一个列表的敌方坦克
	 */
	public List<Tank> tanks = new ArrayList<Tank>();

	/**
	 * 定义缓存的虚拟图片
	 */
	Image offScreenImage = null;

	public NetClient net = new NetClient(this);

	ConnDialog dialog = new ConnDialog();

	@Override
	public void paint(Graphics g) {

		for (int i = 0; i < missiles.size(); i++) {
			// 拿出子弹
			Missile m = missiles.get(i);
			// m.hitTanks(tanks);
			if (m.hitTank(myTank)) {
				TankDeadMsg msg = new TankDeadMsg(myTank.id);
				net.send(msg);
				MissileDeadMsg mdmMsg = new MissileDeadMsg(m.tankId, m.id);
				net.send(mdmMsg);
			}
			// 把它画出来
			m.draw(g);
		}

		for (int i = 0; i < explodes.size(); i++) {
			Explode e = explodes.get(i);
			e.draw(g);
		}

		for (int i = 0; i < tanks.size(); i++) {
			Tank t = tanks.get(i);
			t.draw(g);
		}
		// 利用myTank画坦克方法
		myTank.draw(g);
	}

	/**
	 * 屏幕刷新频率太快，paint方法没有完成就又一次被调用， 产生闪烁现象，所以采用双缓冲先画出虚拟图像，再一次性调用图片
	 **/
	@Override
	public void update(Graphics g) {
		// 创建一张新的图片，大小和原窗口一样，用NULL来防止不必要的创建新图片
		if (offScreenImage == null) {
			offScreenImage = this.createImage(GAMME_WIDTH, GAMME_HEIGHT);
		}
		// 将图片的画笔取出
		Graphics gOffScreen = offScreenImage.getGraphics();
		// 得到原图像的颜色
		Color c = gOffScreen.getColor();
		// 设置图片的背景颜色
		gOffScreen.setColor(Color.LIGHT_GRAY);
		// 填写一个实心方块
		gOffScreen.fillRect(0, 0, GAMME_WIDTH, GAMME_HEIGHT);
		// 将设置好的背景色填进图片
		gOffScreen.setColor(c);
		// 画出图片
		paint(gOffScreen);
		// 把缓存图片显示到屏幕上
		g.drawImage(offScreenImage, 0, 0, null);
	}

	public void lauchFrame() {

		this.setLocation(400, 300);
		this.setSize(GAMME_WIDTH, GAMME_HEIGHT);
		this.setTitle("TankWar");
		this.addWindowListener(new WindowAdapter() {
			@Override
			// 匿名类关闭窗口
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});// 窗口可关闭
			// 窗口大小固定
		this.setResizable(false);
		// 背景为绿色
		this.setBackground(Color.WHITE);
		// 开始监听键盘操作
		this.addKeyListener(new KeyMonitor());

		setVisible(true);

		// 开启一个画图像的进程

		Thread t = new PaintThread();
		t.start();

		// net.connect("127.0.0.1",TankServer.TCP_PORT);
	}

	public static void main(String[] args) {
		// 创建一个窗口
		TankClient tc = new TankClient();
		tc.lauchFrame();

	}

	/**
	 * 内部类，调用外部包装类的repaint方法，只对坦克这个对象有用，所以设为内部类
	 * 
	 * @author
	 *
	 */
	private class PaintThread extends Thread {
		@Override
		public void run() {
			while (true) {
				repaint();
				try {
					// 设定20ms刷新一次坦克的位置
					Thread.sleep(20);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 内部类,定义键盘监听器。不用接口，接口需要写所有的方法，用继承的方法
	 * 
	 * @author
	 *
	 */
	private class KeyMonitor extends KeyAdapter {

		@Override
		// 按键抬起
		public void keyReleased(KeyEvent e) {
			myTank.keyReleased(e);
		}

		@Override
		// 按键按下
		public void keyPressed(KeyEvent e) {
			int key = e.getKeyCode();
			if (key == KeyEvent.VK_C) {
				dialog.setVisible(true);
			} else {
				// 用坦克对象的方法决定坦克的移动
				myTank.keyPressed(e);
			}
		}

	}

	/**
	 * 进入联机游戏的界面
	 * 
	 * @author
	 *
	 */
	class ConnDialog extends Dialog {
		/**
		 * 
		 */
		private static final long serialVersionUID = 2354064968892124911L;
		Button button = new Button("确定");
		TextField ipInfo = new TextField("127.0.0.1", 12);
		TextField portInfo = new TextField("" + TankServer.TCP_PORT, 4);
		TextField udpPortInfo = new TextField("2020", 4);

		public ConnDialog() {
			super(TankClient.this, true);

			this.setLayout(new FlowLayout());
			this.add(new Label("IP:"));
			this.add(ipInfo);
			this.add(new Label("Port:"));
			this.add(portInfo);
			this.add(new Label("连接端口"));
			this.add(udpPortInfo);
			this.add(button);
			this.setLocation(800, 500);
			this.pack();
			this.addWindowListener(new WindowAdapter() {
				@Override
				public void windowClosing(WindowEvent e) {
					setVisible(false);
				}
			});
			button.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					String ip = ipInfo.getText();
					int port = Integer.parseInt(portInfo.getText().trim());
					int myUdpPort = Integer.parseInt(udpPortInfo.getText().trim());
					net.setUdpPort(myUdpPort);
					net.connect(ip, port);
					setVisible(false);

				}
			});
		}

	}
}